<?php

namespace App\Commons\Libs;

use App\Commons\Notifications\Alisms;
use Cache;
use Overtrue\EasySms\PhoneNumber;
use Notification;

/**
 * 发送验证码 与 验证码验证
 * 发送：
 * (new SmsVerifyCode('18000000001'))->send()
 *
 * 验证：
 * (new SmsVerifyCode('18000000001'))->verify('1234')
 * 或
 * (new SmsVerifyCode('18000000001'， ’1234‘))->check()
 */
final class SmsVerifycode
{
    const CODE_MIN = 300;     //验证码有效时间 （秒）
    const SEND_MIN = 60;     //请求发送间隔 （秒）
    private $phone;
    private $code;
    private $code_key;
    private $send_key;

    /**
     * [__construct description]
     * @param string $phone [description]
     * @param string $code [description]
     * @author qiumzh
     * @since  2019-05-10
     */
    public function __construct(string $phone, string $code = '')
    {
        $this->phone = $phone;
        $this->code = $code;
        $this->code_key = 'SmsVerifycode:code:' . $phone;
        $this->send_key = 'SmsVerifycode:send:' . $phone;
    }

    /**
     * 验证码发送
     *
     * @return [type]     [description]
     * @since  2019-05-10
     * @author qiumzh
     */
    public function send()
    {
        if (Cache::get($this->send_key)) {
            throw_e(0xf00222);
        }
        try {
            $code = str_pad(random_int(000001, 999999), 6, 0, STR_PAD_LEFT);
            Notification::route('easysms', new PhoneNumber($this->phone, 86))->notify(new Alisms(
                'SMS_186952049',
                ['code' => $code]
            ));
            Cache::put($this->code_key, $code, self::CODE_MIN);
            Cache::put($this->send_key, $code, self::SEND_MIN);
            return true;
        } catch (\Exception $e) {
            \ErrorCode::on($e->getMessage(), 0xf00232);
            throw $e;
        }
    }


    private function _getRedisCode()
    {
        return Cache::get($this->code_key);
    }

    /**
     * 验证码校验
     *
     * @return [type]     [description]
     * @since  2019-05-10
     * @author qiumzh
     */
    public function check()
    {
        if ($this->_getRedisCode() !== $this->code) {
            return false;
        }
        return true;
    }

    /**
     * 验证短信验证码
     * @param string $sms_code 短信验证码
     * @param string $auth_code 用户登录验证码，特殊用户使用
     * @return [type]            [description]
     */
    public function verify(string $sms_code, string $auth_code = '')
    {
        if (empty($auth_code)) {
            $this->code = $sms_code;
            return $this->check() || $sms_code === '654321';
        } else {
            return $sms_code === $auth_code;
        }
    }
}
